package cn.ivicar.cloud.quartz;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import cn.ivicar.cloud.cache.Interaction;
import cn.ivicar.cloud.cache.Shadow;
import cn.ivicar.cloud.engine.RuleEngine;
import cn.ivicar.cloud.guice.IvicarGuice;
import cn.ivicar.cloud.utils.DataType;
import cn.ivicar.cloud.utils.EventType;
import cn.ivicar.redis.JedisClusterFactory;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisCluster;

public class Inspector implements Job {
    private static transient final Logger LOGGER = LoggerFactory.getLogger(Inspector.class);

    // 设备失联判断时长阈值（天）
    private static int OFFLINE_TIME_THRESHOLD = 2;

    private static Interaction interaction = IvicarGuice.injector.getInstance(Interaction.class);
    private static Shadow shadow = IvicarGuice.injector.getInstance(Shadow.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, 0 - OFFLINE_TIME_THRESHOLD);
        Date anchor = c.getTime();

        Map<String, String> interEntries = interaction.getAllInteraction();
        for (Map.Entry<String, String> entry : interEntries.entrySet()) {
            String clientId = entry.getKey();
            long timestamp = Long.valueOf(entry.getValue());
            if (anchor.getTime() > timestamp) {
                // 超过48小时未上报数据
                if (StringUtils.equals(interaction.getStatus(clientId), "1")) {
                    // 设备由正常变为异常
                    interaction.setStatus(clientId, "0");
                    LOGGER.warn(String.format("设备%s出现异常，已经超过48小时未上报数据", clientId));

                    JedisCluster cluster = JedisClusterFactory.getDefaultJedisCluster();
                    JSONObject event = new JSONObject();
                    event.put("clientId", clientId);
                    event.put("time", anchor.getTime());

                    JSONObject gps = shadow.getShadow(clientId, DataType.GPS);
                    event.put("gps", gps);

                    EventType eventType = EventType.OFFLINE;
                    event.put("event", eventType.getValue());

                    cluster.publish(RuleEngine.IVICAR_EVENT_CHANNEL, event.toString());
                    RuleEngine.influxdb.write(RuleEngine.INFLUXDB_NAME, clientId, DataType.EVENT, event);
                } else {
                    // 设备持续异常
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    LOGGER.warn(String.format("设备%s持续异常，上次数据上报时间%s", clientId, sdf.format(new Date(timestamp))));
                }
            } else {
                if (StringUtils.equals(interaction.getStatus(clientId), "0")) {
                    // 异常设备恢复正常
                    interaction.setStatus(clientId, "1");
                    LOGGER.warn(String.format("设备%s恢复正常工作状态", clientId));

                    JedisCluster cluster = JedisClusterFactory.getDefaultJedisCluster();
                    JSONObject event = new JSONObject();
                    event.put("clientId", clientId);
                    event.put("time", anchor.getTime());

                    JSONObject gps = shadow.getShadow(clientId, DataType.GPS);
                    event.put("gps", gps);

                    EventType eventType = EventType.ONLINE;
                    event.put("event", eventType.getValue());

                    cluster.publish(RuleEngine.IVICAR_EVENT_CHANNEL, event.toString());
                    RuleEngine.influxdb.write(RuleEngine.INFLUXDB_NAME, clientId, DataType.EVENT, event);
                }
            }
        }
    }
}
